The present invention relates generally to accessing objects in a computer system and more particularly to accessing objects of different thread types.
Most computer systems execute under the control of a multiprocessing operating system. A multiprocessing operating system is designed to control the concurrent execution of multiple computer programs. Such operating systems typically allow one program to execute for a while, and then allow another computer program to execute. Before each computer program is allowed to execute, the operating system initializes the system resources (e.g., CPU registers) to their state when that computer program last executed and, if necessary, loads the computer program back into memory. Thus, when the computer program is allowed to execute again, its execution continues where it left off. Each executing computer program is generally referred to as a xe2x80x9cprocess,xe2x80x9d and the state of the computer system when that computer program executes is referred to as the xe2x80x9ccontextxe2x80x9d of the process.
Computer programs that are executing concurrently may have the need to communicate with each other. A computer application may be implemented as multiple cooperating computer programs that each execute as separate processes. One computer program may request another computer. program to perform a certain function on its behalf. Each time the operating system allows a different computer program to execute, the operating system performs what is referred to as a process context switch. The context switch involves saving the current state of the executing process so that it can continue execution at a later time, and restoring the previous state of the computer program to be executed. The saving and restoring of the contexts may place an unacceptable overhead on the computer system. To avoid the overhead of process context switching, some operating systems have implemented the concept of a lightweight process or a thread. Within a single process, the operating system may allow several threads to execute concurrently. Each thread in a process shares the same address space (i.e., code and data), but each thread has its own program counter and other register values. The operating system allows each thread in the process to execute for a while and then switches control to the next thread. Because the threads share the same address space, the context switching from one thread to another can be accomplished much faster than switching from one process to another. Thus, the concept of multithreading allows many of the advantages of multiprocessing, but without the overhead of process context switches.
Many server computer programs (i.e., servers) that provide services to multiple client computer programs (i.e., clients) are implemented using multiple threads. When a client requests the server to perform a service on behalf of the client the server will create a thread to provide that service for the client. Thus, when multiple clients request services at approximately the same time, the server will be executing many threads. The data that a process accesses is often organized into objects that encapsulate data and code for accessing that data. Because the threads within a process share the same data, access control to the data must be coordinated by the threads. With such a multithreading server, the developer of the server is responsible for coordinating access to the objects so that the processing by one thread will not be interfered with by another thread. For example, the developer may need to ensure that appropriate synchronization mechanism (e.g., locks and semaphores) are defined for each object. A synchronization problem could occur when two threads attempt to access an object concurrently. For example, if both threads A and B need to modify the same object, then a synchronization problem could occur in the following way. When the object provides a method to increment a data member, the method may load the value of the data member into a register, increment the value, and store the value back into the data member. However, if thread A invokes the method, the current value (e.g., 10) of the data member may get loaded into a register and then a thread context switch may occur so that thread B executes. If thread B also invokes the method, the current value (e.g., 10) of the data member would be loaded into a register, incremented (e.g., 11), and stored back into the data member. When thread A again executes, it resumes execution of the method. In this case, the value (ie., 10) in its register is incremented (e.g., 11) and stored back into the data member. Thus, after execution of the method by both threads the data member will have a value of 11 rather than the expected value of 12. It may take a considerable amount of programming to develop a computer program that avoids various synchronization problems. The synchronization problems also occur when multiple processes, even with only one thread each, access shared memory. Thus, in general the problems occur when any threads, regardless of whether they are in the same or different processes, access objects in shared memory.
To help simplify development of such objects, an apartment model has been developed. According to the apartment model, each object can only be accessed by the single thread. Because each object can only be accessed by a single thread no synchronization problems occur as a result of multiple threads accessing the object concurrently. That is, the single thread can serially process each request to access the object. Thus, when a thread wants to access an object, it requests that the thread for the object perform the function on behalf of the requesting thread. The group of objects that can be accessed by a thread is referred to as an apartment. The apartment model is described in U.S. patent Ser. No. 08/381,635, entitled xe2x80x9cMethod and, System for Multithreaded Processing,xe2x80x9d which is hereby incorporated by reference. A preferred technique for sending the request from one thread to another is referred to as marshaling and described in U.S. patent Ser. No. 5,511,197, entitled xe2x80x9cMethod and System for Network Marshalling of Interface Pointers for Remote Procedure Calls,xe2x80x9d which is hereby incorporated by reference.
When a programmer is developing a new object, the programmer needs to make a decision as to whether the object will be accessed only by a single thread or by multiple threads. If the object is to be accessed only by a single thread (i.e., an apartment-threaded object), then the implementation of the object is fairly straightforward because synchronization problems can be avoided by serializing access. Conversely, if the object is to be accessed by multiple threads in a multithreaded apartment (i.e., a free-threaded object), then the appropriate synchronization management mechanisms need to be developed. Unfortunately, apartment-threaded objects cannot be accessed by a client developed to access objects from any thread. When free-threaded objects are being used, a client is developed to simply pass pointers to the objects from one thread to another thread. The receiving thread would access the object directly, regardless of which thread created the object. Thus, if such a client loaded an apartment-threaded object, synchronization problems may occur as multiple threads accessed the object concurrently. Consequently, each class of object has an associated thread type. The thread type of the class can be either apartment-threaded or free-threaded. Two other thread types can be defined: single-threaded objects and both-threaded objects. A single-threaded object (referred to as a main-threaded object in the following) is an apartment-threaded object that can only be loaded into the apartment for the main thread of the process. A both-threaded object is compatible with both the apartment model and the free-threading model and thus can be loaded by a process that uses either model.
Many objects have been developed, in accordance with the Microsoft Component Object Model (xe2x80x9cCOMxe2x80x9d), that are apartment-threaded, free-threaded, main-threaded, or both-threaded. COM is described in xe2x80x9cInside OLE, Second Edition,xe2x80x9d by Kraig Brockschmidt and published by Microsoft Press, which is hereby incorporated by reference. It would be desirable if these objects could be accessed by programs that were not developed to adhere to COM. For example, programs written in the Java programming language typically do not adhere to COM. However, it would be desirable if Java programs could access COM objects of varying thread types in a manner that is transparent to the Java program. Such accessibility would be especially useful in Web pages developed for the World-Wide Web. Such Web pages often contain Java applets that are executed by the Java virtual machine (xe2x80x9cVMxe2x80x9d) when the Web page is presented (typically by a Web browser). A Java VM provides a multithreaded execution environment for the Java programming language. These Java applets could take advantage of the functionality of the COM objects that have already been developed. However, a programmer of the Java applet would currently need to develop the applet so that it adheres to the COM. It would be desirable to have a mechanism in which a Java applet could access COM objects without having to be concerned of the COM threading model.
The present invention provides a method and system for accessing object of varying thread types in a manner that is transparent to the computer program accessing the objects. The thread types of the objects are categorized as thread-safe and not thread-safe. The free-threaded and both-threaded objects are thread-safe, and the apartment-threaded and main-threaded objects are not thread-safe. The thread system of the present invention creates a thread, designated as the apartment thread, for receiving message to instantiate objects and to invoke methods of the instantiated objects. When the program designates to instantiate an object, the thread system determines the thread type of the object. When the thread type is not thread-safe, the thread system sends a message to the appropriate thread (i.e., apartment or main thread) to instantiate the object. When the thread type is thread-safe, the thread system instantiates the object within the currently executing thread. When the program designates to invoke a method of the instantiated object, if the object is not thread-safe, then the thread system sends a message to the appropriate thread to invoke the method of the instantiated object If the object is thread-safe, then the thread system invokes the method of the instantiated object directly from the current thread.
In another aspect of the present invention, the thread system determines whether a object can be accessed from the current thread without knowing the class or thread type of the object. When the thread system is returned a pointer to an object from a returning thread, the thread system then requests the returning thread to marshal another pointer to the object. If the marshaled pointer has the same value as the returned pointer, then the object can be access directly from the current thread. If, however, the pointers are not the same, then the marshaled pointer points to a proxy object and the object needs to be accessed by the returning thread. In this way, the thread system can determine when a returned object can be access from the current thread and thus avoid the overhead of requesting the returning thread to access the object.